package org.example.now.async.downloadexcel;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.*;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.example.old.converter.CommentWriteHandler;
import org.example.old.converter.CustomCellWriteHandler;
import org.example.old.converter.CustomSheetWriteHandler;
import org.example.old.converter.DemoStyleStrategy;
import org.example.old.dto.ImageDemoData;
import org.example.old.dto.SysDto;
import org.example.old.dto.SystemDTO;
import org.example.old.dto.WriteCellDemoData;
import org.example.old.service.SysService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;


@RestController
@RequestMapping("/sys2")
public class DownLoadExcel {
    @Autowired
    SysService sysService;

    /**
     * 全量查询数据
     * @return
     */
    public List<SysDto> data() {
        return sysService.querList();
    }

    /**
     * 简单导出数据--easyexcel   2s
     */
    @GetMapping("/queryList")
    public void queryList(){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 写法1
//        EasyExcel.write(filePath, SysDto.class)
//                .sheet(sheetName)
//                .doWrite(() -> {
//                    // 分页查询数据
//                    return data();
//                });
        // 写法2
//        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        // 写法3
        try(ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build()){
            WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(data(),writeSheet1);
        }
     }



    /**
     * 分页导出数据--easyexcel    3.89s
     */
    @GetMapping("/queryList2")
    public void queryList2(){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";

        int sum = sysService.queryCount();
        int num = 3000;
        int time = sum/num +1;

        ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build();
        WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName).build();

        for(int i=0;i<time;i++){
            int finalI = i;
            // 分页获取数据
            List<SysDto> list = new ArrayList<>();
            list.addAll(sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num));
            // 写入数据
            excelWriter.write(list,writeSheet1);
        }
        excelWriter.finish();
    }


    /**
     * 多线程异步导出数据--easyexcel    3.71s
     */
    @GetMapping("/queryList4")
    public CompletableFuture<Void> queryList4(HttpServletResponse response) {
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";

        int sum = sysService.queryCount();
        int num = 3000;
        int time = sum/num +1;
        return CompletableFuture.runAsync(()->{
            ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build();
            for(int i=0;i<time;i++){
                int finalI = i;
                // 分页获取数据
                List<SysDto> list = new ArrayList<>();
                list.addAll(sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num));

                WriteSheet writeSheet1 = EasyExcel.writerSheet(i,sheetName).build();
                // 写入数据
                excelWriter.write(list,writeSheet1);
            }
            excelWriter.finish();
        });
    }


    /**
     * 多线程异步导出数据--easyexcel    3.89s
     */
    @GetMapping("/queryList3")
    public String queryList3(HttpServletResponse response){
        Executor exportThreadPoolExecutor = null;
        CompletableFuture.runAsync(()->{

        },exportThreadPoolExecutor).exceptionally(e->{
            System.out.println("失败："+e);
            return null;
        });
        return "ok";


//        String filePath = "D:/demo.xlsx";
//        String sheetName = "Sheet1";
//
//        int sum = sysService.queryCount();
//        int num = 3000;
//        int time = sum/num +1;
//
//        ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build();
//        WriteSheet writeSheet1 = EasyExcel.writerSheet(sheetName).build();
//
//        for(int i=0;i<time;i++){
//            int finalI = i;
//            // 分页获取数据
//            List<SysDto> list = new ArrayList<>();
//            list.addAll(sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num));
//            // 写入数据
//            excelWriter.write(list,writeSheet1);
//        }
    }

    /**
     * 指定参数只导出指定列--easyexcel
     * 创建excel对应的实体对象
     * 根据自己或者排除自己需要的列
     * 直接写即可
     */
    @GetMapping("/queryList5")
    public String queryList5(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 根据用户传入字段，假设忽略updateDate
//        Set<String> names = new HashSet<>();
//        names.add("updateDate");
//        // 方法一： 这里需要指定用些哪个class去写，然后写到第一个sheet，名字为模版，然后文件流会自动关闭
//        // 方法二：在实体类添加注解@ExcelIgnore进行忽略字段
//        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());


        // 根据用户传入字段，假设指定updateDate
        Set<String> names = new HashSet<>();
        names.add("updateDate");
        // 方法一： 这里需要指定用些哪个class去写，然后写到第一个sheet，名字为模版，然后文件流会自动关闭
        // 方法二：在实体类指定字段，可使用注解：@ExcelProperty("修改时间")
        EasyExcel.write(filePath, SysDto.class).includeColumnFieldNames(names).sheet(sheetName).doWrite(data());

        return "ok";
    }


    /**
     * 复杂表头--easyexcel
     */
    @GetMapping("/queryList6")
    public String queryList6(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        return "ok";
    }



    /**
     * 重复多次写入（单个或多个sheet）--easyexcel
     */
    @GetMapping("/queryList7")
    public String queryList7(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        int sum = sysService.queryCount();
        int num = 3000;
        int time = sum/num +1;
        // 方法一：如果写到同一个sheet
//        try(ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build()){
//            // 同一个sheet只创建一次
//            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
//            for(int i=0;i<time;i++){
//                int finalI = i;
//                // 分页获取数据
//                List<SysDto> list = new ArrayList<>();
//                list.addAll(sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num));
//
//                // 写入数据
//                excelWriter.write(list,writeSheet);
//            }
//        }

        // 方法2：写不同sheet，同一个对象
//        try(ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build()){
//            for(int i=0;i<time;i++){
//                int finalI = i;
//                // 分页获取数据
//                List<SysDto> list = new ArrayList<>();
//                list.addAll(sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num));
//                // 多次写入sheet名称需不同，否则就是一个sheet
//                WriteSheet writeSheet = EasyExcel.writerSheet(i,i+sheetName).build();
//                // 写入数据
//                excelWriter.write(list,writeSheet);
//            }
//        }

        // 方法3：如果写到不同的sheet，不同的对象
        try(ExcelWriter excelWriter = EasyExcel.write(filePath).build()){
            // 每次都要创建writeSheet 必须指定sheetNo，而且sheetName必须不一样,实体类可变
            for(int i=0;i<time;i++){
                int finalI = i;
                // 分页获取数据
                List<SysDto> list =   sysService.querList2(finalI != 0 ? finalI *num-num+1 : finalI,num);
                // 多次写入sheet名称需不同，否则就是一个sheet
                WriteSheet writeSheet = EasyExcel.writerSheet(i,i+sheetName).head(SystemDTO.class).build();
                // 写入数据
                excelWriter.write(list,writeSheet);
            }
        }
        return "ok";
    }


    /**
     * 日期、数字或自定义格式转换--easyexcel
     */
    @GetMapping("/queryList8")
    public String queryList8(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 图片导出--easyexcel
     */
    @GetMapping("/queryList9")
    public String queryList9(HttpServletResponse response) throws MalformedURLException {
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        String path = "C:\\Users\\FH12819\\Pictures\\ceshi.PNG";
//        URL url = new URL("https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg");

        // 所有的图片都会放在内存
        // 1. 将图片上传到oss 或者其他存储网站: https://www.aliyun.com/product/oss ，然后直接放链接
        // 2. 使用: https://github.com/coobird/thumbnailator 或者其他工具压缩图片
        // 3.  目前本地代码放本地
        try (InputStream inputStream = FileUtils.openInputStream(new File(path))) {
            List<ImageDemoData> list = ListUtils.newArrayList();
            ImageDemoData imageDemoData = new ImageDemoData();
//            list.add(imageDemoData);
//            // 放入5种类型的图片，实际使用只要选一种
//            imageDemoData.setByteArray(FileUtils.readFileToByteArray(new File(path)));
//            imageDemoData.setFile(new File(path));
//            imageDemoData.setString(path);
//            imageDemoData.setInputStream(inputStream);
//            imageDemoData.setUrl(url);

            // 这里演示
            // 需要额外放入文字
            // 而且需要放入2个图片
            // 第一个图片靠左
            // 第二个靠右 而且要额外的占用他后面的单元格
            WriteCellData<Void> writeCellData = new WriteCellData<>();
            imageDemoData.setWriteCellDataFile(writeCellData);
            // 这里可以设置为 EMPTY 则代表不需要其他数据了
            writeCellData.setType(CellDataTypeEnum.STRING);
            writeCellData.setStringValue("额外的放一些文字");

            // 可以放入多个图片
            List<ImageData> imageDataList = new ArrayList<>();
            ImageData imageData = new ImageData();
            imageDataList.add(imageData);
            writeCellData.setImageDataList(imageDataList);
            // 放入2进制图片
            imageData.setImage(FileUtils.readFileToByteArray(new File(path)));
            // 图片类型
            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
            // 上 右 下 左 需要留空
            // 这个类似于 css 的 margin
            // 这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
            imageData.setTop(5);
            imageData.setRight(40);
            imageData.setBottom(5);
            imageData.setLeft(5);

            // 放入第二个图片
//            imageData = new ImageData();
//            imageDataList.add(imageData);
//            writeCellData.setImageDataList(imageDataList);
//            imageData.setImage(FileUtils.readFileToByteArray(new File(path)));
//            imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG);
//            imageData.setTop(5);
//            imageData.setRight(5);
//            imageData.setBottom(5);
//            imageData.setLeft(50);
//            // 设置图片的位置 假设 现在目标 是 覆盖 当前单元格 和当前单元格右边的单元格
//            // 起点相对于当前单元格为0 当然可以不写
//            imageData.setRelativeFirstRowIndex(0);
//            imageData.setRelativeFirstColumnIndex(0);
//            imageData.setRelativeLastRowIndex(0);
//            // 前面3个可以不写  下面这个需要写 也就是 结尾 需要相对当前单元格 往右移动一格
//            // 也就是说 这个图片会覆盖当前单元格和 后面的那一格
//            imageData.setRelativeLastColumnIndex(1);
            list.add(imageDemoData);

            // 写入数据
            EasyExcel.write(filePath, ImageDemoData.class).sheet().doWrite(list);


//            EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
            return "ok";
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }




    /**
     * 超链接、备注、公式、指定单个单元格的样式、单个单元格多种样式--easyexcel
     */
    @GetMapping("/queryList10")
    public String queryList10(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        WriteCellDemoData writeCellDemoData = new WriteCellDemoData();

        // 设置超链接
        WriteCellData<String> hyperlink = new WriteCellData<>("官方网站");
        writeCellDemoData.setHyperlink(hyperlink);
        HyperlinkData hyperlinkData = new HyperlinkData();
        hyperlink.setHyperlinkData(hyperlinkData);
        hyperlinkData.setAddress("https://gitee.com/lxt0520/ProjectManager");
        hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);

        // 设置备注
        WriteCellData<String> comment = new WriteCellData<>("备注的单元格信息");
        writeCellDemoData.setCommentData(comment);
        CommentData commentData = new CommentData();
        comment.setCommentData(commentData);
        commentData.setAuthor("lll");
        commentData.setRichTextStringData(new RichTextStringData("这是一个备注"));
        // 备注的默认大小是按照单元格的大小 这里想调整成4个单元格那么大，所以向后向下各占用了一个单元格
        commentData.setRelativeLastColumnIndex(1);
        commentData.setRelativeLastRowIndex(1);

        // 设置公式
        WriteCellData<String> formula = new WriteCellData<>();
        writeCellDemoData.setFormulaData(formula);
        FormulaData formulaData = new FormulaData();
        formula.setFormulaData(formulaData);
        // 求和第二行到第四行
        formulaData.setFormulaValue("SUM(A2:A4)");

        // 设置样式
        WriteCellData<String> writeStyle = new WriteCellData<>("单元格样式");
        writeStyle.setType(CellDataTypeEnum.STRING);
        writeCellDemoData.setWriteCellStyle(writeStyle);
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        writeStyle.setWriteCellStyle(writeCellStyle);
        // 指定，不然无法显示背景颜色
        writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 绿色
        writeCellStyle.setFillBackgroundColor(IndexedColors.GREEN.getIndex());

        // 设置单个单元格多种样式
        // 设置inMOnery=true 不然会导致无法展示单个单元格多种样式
        WriteCellData<String> richTest = new WriteCellData<>();
        richTest.setType(CellDataTypeEnum.RICH_TEXT_STRING);
        writeCellDemoData.setRichText(richTest);
        RichTextStringData richTextStringData = new RichTextStringData();
        richTest.setRichTextStringDataValue(richTextStringData);
        richTest.setRichTextStringDataValue(richTextStringData);
        richTextStringData.setTextString("红色绿色默认");
        // 前2个字红丝
        WriteFont writeFont = new WriteFont();
        writeFont.setColor(IndexedColors.RED.getIndex());
        richTextStringData.applyFont(0,2,writeFont);

        // 接下来两个字绿色
        writeFont = new WriteFont();
        writeFont.setColor(IndexedColors.GREEN.getIndex());
        richTextStringData.applyFont(2,4,writeFont);

        List<WriteCellDemoData> data = new ArrayList<>();
        data.add(writeCellDemoData);

        EasyExcel.write(filePath, WriteCellDemoData.class).inMemory(true).sheet(sheetName).doWrite(data);
        return "ok";
    }



    /**
     * 根据模板写入--easyexcel
     */
    @GetMapping("/queryList11")
    public String queryList11(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String filePath2 = "D:/" + System.currentTimeMillis() + ".xlsx";
        String sheetName = "Sheet1";
        // 会将filePath的文件写入到filePath2中
        EasyExcel.write(filePath2, SysDto.class) .withTemplate(filePath).sheet().doWrite(data());
        return "ok";
    }

    /**
     * 列宽、行高--easyexcel
     */
    @GetMapping("/queryList12")
    public String queryList12(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 会将filePath的文件写入到filePath2中
        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 注解形式自定义样式--easyexcel
     */
    @GetMapping("/queryList13")
    public String queryList13(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 会将filePath的文件写入到filePath2中
        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 自定义样式--easyexcel
     */
    @GetMapping("/queryList14")
    public String queryList14(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 方法1：使用已有策略




        // 会将filePath的文件写入到filePath2中
        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());
        return "ok";
    }



    /**
     * 合并单元格--easyexcel
     */
    @GetMapping("/queryList15")
    public String queryList15(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        // 方法1：实体类加注解@ContentLoopMerge(eachRow = 2)
//        EasyExcel.write(filePath, SysDto.class).sheet(sheetName).doWrite(data());

        // 方法2：自定义合并单元格策略
//        LoopMergeStrategy loopMergeStrategy = new LoopMergeStrategy(2,0);
        EasyExcel.write(filePath, SysDto.class).registerWriteHandler(new DemoStyleStrategy()).sheet(sheetName).doWrite(data());

        // 若要根据数据的相同性合并单元格，需实现CellWriteHandler
        return "ok";
    }

    /**
     * 使用table去写入--easyexcel
     */
    @GetMapping("/queryList16")
    public String queryList16(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";

        // 方法1 这里直接写多个table的案例了，如果只有一个 也可以直一行代码搞定，参照其他案
        // 这里 需要指定写用哪个class去写
        try (ExcelWriter excelWriter = EasyExcel.write(filePath, SysDto.class).build()) {
            // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(Boolean.FALSE).build();
            // 这里必须指定需要头，table 会继承sheet的配置，sheet配置了不需要，table 默认也是不需要
            WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build();
            WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.TRUE).build();
            // 第一次写入会创建头
            excelWriter.write(data(), writeSheet, writeTable0);
            // 第二次写如也会创建头，然后在第一次的后面写入数据
            excelWriter.write(data(), writeSheet, writeTable1);
        }
        return "ok";
    }

    /**
     * 动态头，实时生成头写入--easyexcel
     */
    @GetMapping("/queryList17")
    public String queryList17(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";

        List<List<String>> list = new ArrayList<>();
        List<String> a = new ArrayList<>();
        a.add("id");
        list.add(a);
        a = new ArrayList<>();
        a.add("name");
        list.add(a);
        a = new ArrayList<>();
        a.add("pwd");
        list.add(a);

        EasyExcel.write(filePath, SysDto.class).head(list).sheet(sheetName).doWrite(data());

        return "ok";
    }

    /**
     * 自动列宽(不太精确)--easyexcel
     */
    @GetMapping("/queryList18")
    public String queryList18(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        EasyExcel.write(filePath, SysDto.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 自定义拦截器（上面几点都不符合但是要对单元格进行操作的参照这个--easyexcel
     */
    @GetMapping("/queryList19")
    public String queryList19(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        EasyExcel.write(filePath, SysDto.class).registerWriteHandler(new CustomSheetWriteHandler())
                .registerWriteHandler(new CustomCellWriteHandler()).sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 插入批注--easyexcel
     */
    @GetMapping("/queryList20")
    public String queryList20(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        EasyExcel.write(filePath, SysDto.class).registerWriteHandler(new CommentWriteHandler())
                .sheet(sheetName).doWrite(data());
        return "ok";
    }

    /**
     * 可变标题处理(包括标题国际化等--easyexcel
     * 看了下网上了国际化逻辑：利用反射机制进行国际化赋值，有些麻烦
     * 我的国际化逻辑（感觉目前还不是很完善，需要提纯数据，最好能封装逻辑，最后只需要传参、传语言就行）：自定义好所有国际化表头名称，然后将数组转成所需集合，然后判断本地环境进行赋值不同的表头。
     *
     */
    @GetMapping("/queryList21")
    public String queryList21(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";

        Locale locale = Locale.getDefault();
        String[] arr = new String[]{"id","用户名称","用户编码","创建时间","创建人","修改时间","修改人","备注"};
        String[] arr2 = new String[]{"id","userName","code","createDate","createUser","updateDate","updateTime","remark"};


        List<String> list = Arrays.asList(arr);
        List<List<String>> partition = ListUtil.partition(list, 1);

        List<String> list2 = Arrays.asList(arr2);
        List<List<String>> partition2 = ListUtil.partition(list2, 1);


//        if(locale.getLanguage().equals("zh-CN")){
//            EasyExcel.write(filePath, SysDto.class).head(partition)
//                    .sheet(sheetName).doWrite(data());
//        }else{
//            EasyExcel.write(filePath, SysDto.class).head(partition2)
//                    .sheet(sheetName).doWrite(data());
//        }
        EasyExcel.write(filePath).head(partition2).sheet("模板").doWrite(data());
        // 网友的逻辑国际化需写util   https://blog.51cto.com/u_15564604/5298602
        return "ok";
    }


    /**
     * 不创建对象的写--easyexcel
     */
    @GetMapping("/queryList22")
    public String queryList22(HttpServletResponse response){
        String filePath = "D:/demo.xlsx";
        String sheetName = "Sheet1";
        String[] arr2 = new String[]{"id","userName","code","createDate","createUser","updateDate","updateTime","remark"};
        List<String> list2 = Arrays.asList(arr2);
        List<List<String>> partition2 = ListUtil.partition(list2, 1);

        EasyExcel.write(filePath).head(partition2).sheet("模板").doWrite(data());
        return "ok";
    }

    /**
     * web中的写--easyexcel
     */
    @GetMapping("/queryList23")
    public String queryList23(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + System.currentTimeMillis() + ".xlsx");
        String[] arr2 = new String[]{"id","userName","code","createDate","createUser","updateDate","updateTime","remark"};
        List<String> list2 = Arrays.asList(arr2);
        List<List<String>> partition2 = ListUtil.partition(list2, 1);

        EasyExcel.write(response.getOutputStream()).head(partition2).sheet("模板").doWrite(data());
        return "ok";
    }

    /**
     *  web中的写并且失败的时候返回json--easyexcel
     *  文件下载并且失败的时候返回json（默认失败了会返回一个有部分数据的Excel）
     */
    @GetMapping("/queryList24")
    public void queryList24(HttpServletResponse response) throws IOException {
        try{
//            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//            response.setCharacterEncoding("UTF-8");
//            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + System.currentTimeMillis() + ".xlsx");
//            String[] arr2 = new String[]{"id","userName","code","createDate","createUser","updateDate","updateTime","remark"};
//            List<String> list2 = Arrays.asList(arr2);
//            List<List<String>> partition2 = ListUtil.partition(list2, 1);
//
//            EasyExcel.write(response.getOutputStream()).head(partition2)
//                    .autoCloseStream(Boolean.FALSE).sheet("模板").doWrite(data());
            throw new IOException();
        } catch (IOException e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            Map<String,String> map = MapUtils.newHashMap();
            map.put("status","failure");
            map.put("message","文件下载失败"+e.getMessage());
            response.getWriter().println(map);
        }

//        return "ok";
    }











}
